package de.fhin.mas.agents.gripper;

import jade.lang.acl.ACLMessage;
import de.fhin.mas.MASEvents;
import de.fhin.mas.MASServices;
import de.fhin.mas.agents.MASBaseAgent;
import de.fhin.mas.agents.gripper.behaviours.ListenToMessages;
import de.fhin.mas.ontology.SearchableObject;

public class GripperAgent extends MASBaseAgent {

	private static final long serialVersionUID = -2328064151049697973L;

	private String grapplerStatus = "STANDBY";
	private String resumeStatus = "NULL";

	// Array mit greifbaren Objekten
	private static SearchableObject[] SizeableObjectArray = new SearchableObject[] { 
		new SearchableObject("Huettchen", "orange", "rund", 400, 150, 150),
		new SearchableObject("Lego Stein", "rot", "rechteckig", 10, 5, 3), 
		new SearchableObject("Schild", "gelb", "dreieck", 300, 300, 5),
		new SearchableObject("Zylinder", "blau", "zylindrisch", 300, 10, 10), 
		new SearchableObject("Würfel", "schwarz", "quadratisch", 400, 400, 400),
		new SearchableObject("Schraube", "grau", "konisch", 10, 2, 2) };

	public GripperAgent() {
		super(MASServices.GRIPPER);
	}

	// Aktueller Status des Greifers
	public void setGrapplerStatus(String status) {
		if (status == "STANDBY" || status == "TRANSPORT" || status == "TAKEUP" || status == "PUTDOWN" || status == "STOPPED" || status == "ABORTED" || status == "PROBLEM")
			grapplerStatus = status;
		else
			throw new IllegalArgumentException("Exception: Valid arguments for setGrapplerStatus(String status) are:\nSTANDBY,TRANSPORT,TAKEUP,PUTDOWN,STOPPED,ABORTED,PROBLEM ");
	}

	public String getGrapplerStatus() {
		return grapplerStatus;
	}

	// Status des Greifers nach einem SYSTEM_STOP_REQUIRED oder ABORT_AND_GO_TO
	public void setResumeStatus(String status) {
		if (status == "NULL" || status == "SSR_STANDBY" || status == "SSR_TRANSPORT" || status == "SSR_TAKEUP" || status == "SSR_PUTDOWN" || status == "AGT_STANDBY" || status == "AGT_TRANSPORT")
			resumeStatus = status;
		else
			throw new IllegalArgumentException("Exception: Valid arguments for setGrapplerStatus(String status) are:\nNULL,SSR_STANDBY,SSR_TRANSPORT,SSR_TAKEUP,SSR_PUTDOWN,AGT_STANDBY,AGT_TRANSPORT ");
	}

	public String getResumeStatus() {
		return resumeStatus;
	}

	// Überprüft ob das gesuchte Objekt in dem Array der greifbaren Objekte enthalten ist
	public Boolean isSizeable(ACLMessage msg) {
		SearchableObject searchableObject = null;
		Boolean sizeable = false;
		// Message ist vom Typ Ontologie
		if (msg.getOntology() != null) {
			searchableObject = this.extractSearchableObjectFromMsg(msg);
			for (SearchableObject sizeableObject : SizeableObjectArray) {
				if (searchableObject.toString().equals(sizeableObject.toString())) {
					this.printLn("Object sizeable: " + searchableObject.getName() + ", " + searchableObject.getColor() + ", " + searchableObject.getShape() + ", W(" + searchableObject.getWidth()
							+ ") H(" + searchableObject.getHeight() + ") D(" + searchableObject.getDepth() + ")");
					sizeable = true;
				}
			}
			if (sizeable == false) {
				this.printLn("Object not sizeable: " + searchableObject.getName() + ", " + searchableObject.getColor() + ", " + searchableObject.getShape() + ", W(" + searchableObject.getWidth()
						+ ") H(" + searchableObject.getHeight() + ") D(" + searchableObject.getDepth() + ")");
			}
		} else {
			this.printLn("Missing objekt-ontology. Object not sizeable!");
		}
		return sizeable;
	}

	// Gibt zufällig den Booleanwert true oder false zurück
	public boolean getRandomBoolean() {
		boolean randomBoolean = (Math.random() > 0.5) ? true : false;
		return randomBoolean;
	}

	@Override
	protected void addBehaviours() {
		addBehaviour(new ListenToMessages(this));
	}

	/**
	 * Subscriben zu den für den Gripper-Agent nötigen Message-Topics.
	 */
	@Override
	protected void addTopicSubsciptions() {
		subscribeToTopic(MASEvents.ABORT_AND_GO_TO);
		subscribeToTopic(MASEvents.MOVEMENT_OF_PLATFORM_NECESSARY);
		subscribeToTopic(MASEvents.NEW_ORDER);
		subscribeToTopic(MASEvents.RESUME);
		subscribeToTopic(MASEvents.STORAGE_REACHED);
		subscribeToTopic(MASEvents.SYSTEM_STOP_REQUIRED);
		subscribeToTopic(MASEvents.TARGET_OBJECT_REACHED);

		subscribeToTopic(MASEvents.LOADING_OBJECT);
		subscribeToTopic(MASEvents.UNLOADING_OBJECT);
		subscribeToTopic(MASEvents.OBJECT_UNLOADED);
		subscribeToTopic(MASEvents.OBJECT_OUT_OF_REACH);
		subscribeToTopic(MASEvents.OBJECT_LOST);
		subscribeToTopic(MASEvents.OBJECT_UNSEIZABLE);
	}
}
